//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
// Base class for the Account Loader/Saver
//////////////////////////////////////////////////////////////////////
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "definitions.h"
#include "ioaccount.h"

#include <algorithm>
#include <functional>
#include <sstream>

#include "database.h"
#include <iostream>

#include "configmanager.h"

extern ConfigManager g_config;

Account IOAccount::loadAccount(uint32_t accno)
{
	Account acc;
	time_t premEnd;

	uint32_t premDays;
	uint32_t today = uint32_t(time(NULL) / 86400);

	Database* db = Database::instance();
	DBQuery query;
	DBResult* result;

    #ifndef DT_PREMIUM_SYSTEM
	query << "SELECT `id`, `password` FROM `accounts` WHERE `id` = " << accno;
	#else
	query << "SELECT `id`, `password`, `premend` FROM `accounts` WHERE `id` = " << accno;
	#endif // DT_PREMIUM_SYSTEM
	
	if((result = db->storeQuery(query.str()))){
		acc.accnumber = result->getDataInt("id");
		acc.password = result->getDataString("password");
		#ifdef DT_PREMIUM_SYSTEM
		premEnd = result->getDataInt("premend");
		if( premEnd > std::time( NULL ) )
		{
            acc.premEnd = premEnd;
            acc.premDays = uint32_t(premEnd / 86400) - today;
        }
        else
        {
            acc.premEnd = 0;
            acc.premDays = 0;
        }
		#endif // DT_PREMIUM_SYSTEM
		db->freeResult(result);

		query.str("");

		query << "SELECT `name`, `premend` FROM `players` WHERE `account_id` = " << accno;

		if((result = db->storeQuery(query.str()))){
			do {
				std::string ss = result->getDataString("name");
				acc.charList.push_back(ss.c_str());
				#ifndef DT_PREMIUM_SYSTEM
				premEnd = result->getDataInt("premend");
				premDays = uint32_t(premEnd / 86400) - today;
				// give the account the highest number of premium days
				if(premDays > acc.premDays) {
					acc.premDays = premDays;
				}
				#endif // DT_PREMIUM_SYSTEM

			} while(result->next());

			acc.charList.sort();
			db->freeResult(result);
		}
	}

	return acc;
}

bool IOAccount::getPassword(uint32_t accno, const std::string &name, std::string &password)
{
	Database* db = Database::instance();
	DBQuery query;
	DBResult* result;

	query << "SELECT `accounts`.`password` AS `password` FROM `accounts`, `players` WHERE `accounts`.`id` = " << accno << " AND `accounts`.`id` = `players`.`account_id` AND `players`.`name` = " << db->escapeString(name);
	if((result = db->storeQuery(query.str()))){
		password = result->getDataString("password");
		db->freeResult(result);
		return true;
	}

	return false;
}

#ifdef DT_PREMIUM_SYSTEM
bool IOAccount::savePremiumEnd( uint32_t accno, time_t premEnd )
{
     Database* db = Database::instance();
     DBQuery query;
     
     query << "UPDATE `accounts` SET `premend` = " << premEnd << " WHERE `id` = " << accno;
     
     DBTransaction transaction(db);
     if(!transaction.begin())
     		return false;

     if(!db->executeQuery(query.str())){
     	 	return false;
     }
     
     return transaction.commit();
     
}
#endif // DT_PREMIUM_SYSTEM

#ifdef DT_RULEVIOLATIONS
bool IOAccount::isAccountWarned( uint32_t accno )
{
    Database* db = Database::instance();
	DBQuery query;
	DBResult* result;    
	
	query << "SELECT "
			"COUNT(*) AS `count` "
            "FROM "
            "`accounts` WHERE `warned`=1 AND `id`=" << accno << ";";
   
   	if(result = db->storeQuery(query.str())){
		int t = result->getDataInt("count");
		db->freeResult(result);
		return t > 0;
	}
	return false;
}

void IOAccount::warnAccount( uint32_t accno )
{
     Database* db = Database::instance();
     DBQuery query;
     DBTransaction transaction(db);
     
     if( isAccountWarned( accno ) )
         query << "UPDATE `accounts` SET `deleted` = 1 WHERE `id` = " << accno;
     else
         query << "UPDATE `accounts` SET `warned` = 1 WHERE `id` = " << accno;
         
     if(!transaction.begin())
   		return;

     if(!db->executeQuery(query.str())){
  	 	return;
     }
     
     transaction.commit();
}
#endif // DT_RULEVIOLATIONS
     
     
         
         
